package com.yystudy.rpc.fault.retry;

import com.github.rholder.retry.*;
import com.yystudy.rpc.model.RpcResponse;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * 固定时间间隔 - 重试策略
 *
 */
@Slf4j
public class FixedIntervalRetryStrategy implements RetryStrategy {

    /**
     * 重试
     *
     * @param callable  请求任务
     * @return  响应结果
     * @throws ExecutionException
     * @throws RetryException
     */
    public RpcResponse doRetry(Callable<RpcResponse> callable) throws ExecutionException, RetryException {
        Retryer<RpcResponse> retryer = RetryerBuilder.<RpcResponse>newBuilder()
                // 出现 Exception 异常时重试
                .retryIfExceptionOfType(Exception.class)
                // fixedWait 固定时间间隔策略：3秒一次
                .withWaitStrategy(WaitStrategies.fixedWait(3L, TimeUnit.SECONDS))
                // 超过最大重试次数3停止
                .withStopStrategy(StopStrategies.stopAfterAttempt(3))
                .withRetryListener(new RetryListener() {
                    @Override
                    public <V> void onRetry(Attempt<V> attempt) {
                        // 每次重试前，打印一下日志
                        log.info("重试次数 {}", attempt.getAttemptNumber());
                    }
                })
                .build();

        // 开始重试
        return retryer.call(callable);
    }

}